package com.xinshujia.config.authentication.provider;

import com.google.gson.Gson;
import com.xinshujia.config.authentication.service.MyUsernamePasswordDetailsService;
import com.xinshujia.entity.UserEntity;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author: 野狼上校
 * @create: 2023-03-23  18:10
 * @version: 1.0
 * @description: 账号登录 认证处理器
 */
@Component
public class MyUsernamePasswordAuthenticationProvider implements AuthenticationProvider {

    private final MyUsernamePasswordDetailsService myUsernamePasswordDetailsService;

    public MyUsernamePasswordAuthenticationProvider(MyUsernamePasswordDetailsService myUsernamePasswordDetailsService) {
        this.myUsernamePasswordDetailsService = myUsernamePasswordDetailsService;
    }


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 1. 获取用户输入的信息
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) authentication;
        String username = (String) usernamePasswordAuthenticationToken.getPrincipal();
        String password = (String) usernamePasswordAuthenticationToken.getCredentials();

        // 2. 根据username从数据库中查询用户信息
        UserEntity userEntity = (UserEntity) myUsernamePasswordDetailsService.loadUserByUsername(username);
        if (null == userEntity) {
            throw new BadCredentialsException("账号不存在");
        }
        // 3. 验证密码是否正确(使用DelegatingPasswordEncode加密方案)
        PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        boolean matches = delegatingPasswordEncoder.matches(authentication.getCredentials().toString(), userEntity.getPassword());
        if (!matches) {
            throw new BadCredentialsException("密码不正确");
        }
        // 4. 把用户信息封装到PhoneAuthenticationToken中
        UsernamePasswordAuthenticationToken usernameAuthenticationTokenFull = new UsernamePasswordAuthenticationToken(userEntity, password, userEntity.getAuthorities());
        usernameAuthenticationTokenFull.setDetails(usernamePasswordAuthenticationToken.getDetails());
        return usernameAuthenticationTokenFull;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
